#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <Includes.h>
#include <DRV_EC600S.h>
#include <EC600S_AT/AT.h>
#include <EC600S_AT/AT_Mqtt.h>

int AtResponseQMTPUBEX(char *buffer, int len, unsigned char *exdata)
{
    if(NULL == strstr(buffer,">"))
    {
        return 1;
    }
    return 0;
}

//AT+QMTCFG="keepalive",<client_idx>[,<keep_alive_time>]
ST_CMD qmtcfg_keepaliveCmd[]={
    {"AT_QMTCFG_KEEPALIVE","AT+QMTCFG=\"keepalive\",%d,%d\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTCFG="session",<client_idx>[,<clean_session>]
ST_CMD qmtcfg_sessionCmd[]={
    {"AT_QMTCFG_SESSION","AT+QMTCFG=\"session\",%d,%d\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTCFG="timeout",<client_idx>[,<pkt_timeout>,<retry_times>,<timeout_notice>]
ST_CMD qmtcfg_timeoutCmd[]={
    {"AT_QMTCFG_TIMEOUT","AT+QMTCFG=\"timeout\",%d,%d,%d,%d\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTCFG="recv/mode",<client_idx>[,<msg_recv_mode>[,<msg_len_enable>]]
ST_CMD qmtcfg_recvmodeCmd[]={
    {"AT_QMTCFG_RECV/MODE","AT+QMTCFG=\"recv/mode\",%d,%d,1\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTCFG="qmtping",<client_idx>[,<qmtping_interval>]
ST_CMD qmtcfg_qmtpingCmd[]={
    {"AT_QMTCFG_QMTPING","AT+QMTCFG=\"qmtping\",%d\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTCFG="send/mode",<client_idx>[,<send_mode>]
ST_CMD qmtcfg_sendmodeCmd[]={
    {"AT_QMTCFG_RECV/MODE","AT+QMTCFG=\"send/mode\",%d,%d\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD qmtopenCmd[]={
    {"AT_QMTOPEN","AT+QMTOPEN=%d,\"%s\",%d\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD qmtcloseCmd[]={
    {"AT_QMTCLOSE","AT+QMTCLOSE=%d\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD qmtconnCmd[]={
    {"AT_QMTCONN","AT+QMTCONN=%d,\"%s\",\"%s\",\"%s\"\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD qmtdiscCmd[]={
    {"AT_QMTDISC","AT+QMTDISC=%d\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTSUB=<client_idx>,<msgid>,<topic1>,<qos1>[,<topic2>,<qos2>…]
ST_CMD qmtsubCmd[]={
    {"AT_QMTSUB","AT+QMTSUB=%d,%d%s\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTUNS=<client_idx>,<msgid>,<topic1>[,<topic2>…]
ST_CMD qmtunsCmd[]={
    {"AT_QMTUNS","AT+QMTUNS=%d,%d,%s\r",300,AtResponseComm,NULL,NULL},
};

//AT+QMTPUBEX=<client_idx>,<msgid>,<qos>,<retain>,<topic>,<length>
ST_CMD qmtpubexCmd[]={
    {"AT_QMTPUBEX","AT+QMTPUBEX=%d,%d,%d,%d,\"%s\",%d\r",5000/*300*/,AtResponseQMTPUBEX,NULL,NULL},
};

ST_CMD payloadCmd[]={
    {"AT_PAYLOAD","%s\r",300,AtResponseComm,NULL,NULL},
};

ST_CMD ctrlzCmd[]={
    {"CTRL_Z","\032\r",300,AtResponseComm,NULL,NULL},
};

int Ec600sAT_FASTCONN(ST_FASTCONN_EVENT_PARA *para)
{
    int ret;

    if(para==NULL)
    {
        printf("para is null\r\n");
        return 1;
    }
    printf("fatconn\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtcfg_keepaliveCmd[0], NULL, ATCMD_LEN, para->client_idx,para->keepalive);
    if(0!=ret)
        return 10+ret;
    printf("keepalive\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtcfg_sessionCmd[0], NULL, ATCMD_LEN, para->client_idx,para->cleansession);
    if(0!=ret)
        return 20+ret;
    printf("session\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtcfg_timeoutCmd[0], NULL, ATCMD_LEN, para->client_idx,para->pkt_timeout,para->retry_times,0);
    if(0!=ret)
        return 30+ret;
    printf("timeout\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtcfg_recvmodeCmd[0], NULL, ATCMD_LEN, para->client_idx,para->recv_mode);
    if(0!=ret)
        return 40+ret;
    printf("recv\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtcfg_sendmodeCmd[0], NULL, ATCMD_LEN, para->client_idx,para->send_mode);
    if(0!=ret)
        return 50+ret;
    printf("send\r\n");
    ret=Ec600sAtFmtCmdOne(&qmtopenCmd[0], NULL, ATCMD_LEN, para->client_idx,para->hostname,para->port);
    if(0!=ret)
        return 60+ret;
    printf("open\r\n");

    /*ret=Ec600sAtFmtCmdOne(&qmtconnCmd[0], NULL, ATCMD_LEN, para->client_idx,para->clientid,para->username,para->password);
    if(0!=ret)
        return 70+ret;
    printf("conn\r\n");*/

    return 0;
}


int Ec600sAT_QMTCFG(ST_QMTCFG_EVENT_PARA *para)
{
    int ret;

    ret=Ec600sAtFmtCmdOne(&qmtcfg_keepaliveCmd[0], NULL, ATCMD_LEN, para->client_idx,para->keepalive);
    if(0!=ret)
        return 10+ret;
    ret=Ec600sAtFmtCmdOne(&qmtcfg_sessionCmd[0], NULL, ATCMD_LEN, para->client_idx,para->cleansession);
    if(0!=ret)
        return 20+ret;
    ret=Ec600sAtFmtCmdOne(&qmtcfg_timeoutCmd[0], NULL, ATCMD_LEN, para->client_idx,para->pkt_timeout,para->retry_times,0);
    if(0!=ret)
        return 30+ret;
    ret=Ec600sAtFmtCmdOne(&qmtcfg_recvmodeCmd[0], NULL, ATCMD_LEN, para->client_idx,para->recv_mode);
    if(0!=ret)
        return 40+ret;
    ret=Ec600sAtFmtCmdOne(&qmtcfg_sendmodeCmd[0], NULL, ATCMD_LEN, para->client_idx,para->send_mode);
    if(0!=ret)
        return 50+ret;
    return 0;
}

int Ec600sAT_QMTOPEN(ST_QMTOPEN_EVENT_PARA *para)
{
    return Ec600sAtFmtCmdOne(&qmtopenCmd[0], NULL, ATCMD_LEN, para->client_idx,para->hostname,para->port);
}

int Ec600sAT_QMTCLOSE(ST_QMTCLOSE_EVENT_PARA *para)
{
    return Ec600sAtFmtCmdOne(&qmtcloseCmd[0], NULL, ATCMD_LEN, para->client_idx);
}

int Ec600sAT_QMTCONN(ST_QMTCONN_EVENT_PARA *para)
{
    return Ec600sAtFmtCmdOne(&qmtconnCmd[0], NULL, ATCMD_LEN, para->client_idx,para->clientid,para->username,para->password);
}

int Ec600sAT_QMTDISC(ST_QMTDISC_EVENT_PARA *para)
{
    return Ec600sAtFmtCmdOne(&qmtdiscCmd[0], NULL, ATCMD_LEN, para->client_idx);
}

int Ec600sAT_QMTSUB(ST_QMTSUB_EVENT_PARA *para)
{
    char buffer[128]={0};
    int i;
    int len=0;
    int topic_len=sizeof(ST_TOPIC)*para->topic_num;

    for(i=0;i<para->topic_num;i++)
    {
        len+=sprintf(buffer+len,",\"%s\",%d",para->topics[i].topic,para->topics[i].qos);
    }

    return Ec600sAtFmtCmdOne(&qmtsubCmd[0], NULL, ATCMD_LEN+topic_len, para->client_idx,para->msgid,buffer);
}

int Ec600sAT_QMTUNS(ST_QMTUNS_EVENT_PARA *para)
{
    char buffer[128]={0};
    int i;
    int len=0;
    int topic_len=sizeof(ST_TOPIC)*para->topic_num;

    for(i=0;i<para->topic_num;i++)
    {
        len+=sprintf(buffer+len,",\"%s\",%d",para->topics[i].topic,para->topics[i].qos);
    }

    return Ec600sAtFmtCmdOne(&qmtunsCmd[0], NULL, ATCMD_LEN+topic_len, para->client_idx,para->msgid,buffer);
}

int Ec600sAT_QMTPUBEX(ST_QMTPUBEX_EVENT_PARA *para)
{
    static int ret=0;
    U32 tick_start=0;
    char outbuf[NEUL_MAX_BUF_SIZE] = {0};

    //上次发送失败先发送ctrl+z
    if(ret!=0)
    {
        ret=Ec600sAtCmdOne(&ctrlzCmd[0], NULL);
        if(ret!=0)
        {
            //ctrl+z执行失败再执行次
            //ret=Ec600sAtCmdOne(&ctrlzCmd[0], NULL);
            Ec600sUartDataFlush();
        }
    }

    tick_start=OppTickCountGet();
    ret=Ec600sAtFmtCmdOne(&qmtpubexCmd[0], NULL, ATCMD_LEN+sizeof(ST_TOPIC),
        para->client_idx,para->msgid,para->qos,para->retain,para->topic,para->length);
    if(0!=ret)
    {
        while(OppTickCountGet()-tick_start<qmtpubexCmd[0].waitTime)
        {
            ret=Ec600sDataRead(outbuf, NEUL_MAX_BUF_SIZE, 0, 10);
            if(ret>0)
            {
                if(0==qmtpubexCmd[0].atRspProc(outbuf,ret,NULL))
                {
                    break;
                }
            }
        }
    }

    ret=Ec600sAtFmtCmdOne(&payloadCmd[0], NULL, ATCMD_LEN+para->length, para->payload);
    if(0!=ret)
    {
        return 10+ret;
    }
    return ret;
}

int Ec600sAT_CTRLZ()
{
    return Ec600sAtCmdOne(&ctrlzCmd[0], NULL);
}

